package cn.buk.tms.eotms.service;

import cn.buk.tms.common.constant.TmsOrderConstant;
import cn.buk.tms.common.dto.base.BaseDto;
import cn.buk.tms.eotms.dao.*;
import cn.buk.tms.eotms.dto.CarOrderDto;
import cn.buk.tms.eotms.dto.PaymentOrderDto;
import cn.buk.tms.eotms.dto.VasOrderDto;
import cn.buk.tms.eotms.entity.PaymentOrder;
import cn.buk.tms.eotms.entity.RentalCarOrder;
import cn.buk.tms.eotms.response.FlightOrderResponseDto;
import cn.buk.tms.eotms.response.HotelOrderResponseDto;
import cn.buk.tms.exception.BaseException;
import jakarta.transaction.Transactional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


/**
 * 支付单的处理逻辑
 */
@Component
public class PaymentServiceImpl implements PaymentService {

    private static final Log logger = LogFactory.getLog(PaymentServiceImpl.class);

    @Autowired
    public PaymentServiceImpl(PaymentOrderDao paymentOrderDao,
                              FlightOrderService flightOrderService,
                              FlightOrderDao flightOrderDao,
                              RentalCarService rentalCarService,
                              CarOrderDao carOrderDao,
                              HotelOrderDao hotelOrderDao,
                              HotelOrderService hotelOrderService,
                              VasOrderService vasOrderService,
                              VasOrderDao vasOrderDao) {
        this.paymentOrderDao = paymentOrderDao;
        this.flightOrderDao = flightOrderDao;
        this.flightOrderService = flightOrderService;
        this.hotelOrderDao = hotelOrderDao;
        this.hotelOrderService = hotelOrderService;
        this.rentalCarService = rentalCarService;
        this.carOrderDao = carOrderDao;
        this.vasOrderService = vasOrderService;
        this.vasOrderDao = vasOrderDao;
    }

    private final PaymentOrderDao paymentOrderDao;
    private final FlightOrderDao flightOrderDao;
    private final FlightOrderService flightOrderService;
    private final HotelOrderDao hotelOrderDao;
    private final HotelOrderService hotelOrderService;
    private final RentalCarService rentalCarService;
    private final CarOrderDao carOrderDao;
    private final VasOrderService vasOrderService;
    private final VasOrderDao vasOrderDao;


    @Override
    @Transactional
    public PaymentOrder updatePaymentOrderDone(final String outTradeNo, final double totalAmount, final String tradeNo, final String buyerId) throws BaseException {
        PaymentOrder po =  paymentOrderDao.updatePaymentOrderDone(outTradeNo, totalAmount, PaymentOrder.PAYMENT_ORDER_SUCCESS,
                tradeNo, buyerId);
        if (po.getOrderType() != null) {
            if (po.getOrderType() == TmsOrderConstant.ORDER_TYPE_FLIGHT) {
                //机票订单的在线支付
                FlightOrderResponseDto dto = flightOrderService.getFlightOrderDetail(po.getUserId(), po.getOrderId());

                //校验金额
                double alpha = Math.abs(dto.getTotalAmount() - totalAmount);
                if (alpha > 0.001) {
                    throw new RuntimeException("Total amount is not equal to flight order's.");
                }

                int retCode = flightOrderDao.updateFlightOrderPaid(po.getUserId(), po.getOrderId());
                if (retCode != 1) {
                    throw new RuntimeException("To update flight order paid is failed.");
                }

                //TODO 发送消息出去，提示该订单需要自动提交出票
            } else if (po.getOrderType() == TmsOrderConstant.ORDER_TYPE_HOTEL) {
                //酒店订单的在线支付
                HotelOrderResponseDto dto = hotelOrderService.getHotelOrderById(po.getUserId(), po.getOrderId());

                //校验金额
                double alpha = Math.abs(dto.getTotalAmount() - totalAmount);
                if (alpha > 0.001) {
                    throw new RuntimeException("Total amount is not equal to hotel order's.");
                }

                int retCode = hotelOrderDao.updateHotelOrderPaid(po.getUserId(), po.getOrderId());
                if (retCode != 1) {
                    throw new RuntimeException("To update hotel order paid is failed.");
                }

                //TODO 发送消息出去，提示该订单需要自动处理
            } else if (po.getOrderType() == TmsOrderConstant.ORDER_TYPE_CAR) {
                //租车订单的在线支付
                CarOrderDto dto = rentalCarService.searchRentalCarOrder(po.getUserId(), po.getOrderId());

                //校验金额
                double alpha = Math.abs(dto.getTotalAmount() - totalAmount);
                if (alpha > 0.001) {
                    throw new RuntimeException("Total amount is not equal to rental car order's.");
                }

                int retCode = carOrderDao.updateRentalCarOrderPaid(po.getUserId(), po.getOrderId());
                if (retCode != 1) {
                    throw new RuntimeException("To update rental car order paid is failed.");
                }

                //TODO 发送消息出去，提示该订单需要自动处理
            } else if (po.getOrderType() == TmsOrderConstant.ORDER_TYPE_SERVICE) {
                //机场服务订单的在线支付
                VasOrderDto dto = vasOrderService.getVasOrderById(po.getUserId(), po.getOrderId());

                //校验金额
                double alpha = Math.abs(dto.getTotal() - totalAmount);
                if (alpha > 0.001) {
                    throw new RuntimeException("Total amount is not equal to vaas order's.");
                }

                int retCode = vasOrderDao.updateVasOrderPaid(po.getUserId(), po.getOrderId());
                if (retCode != 1) {
                    throw new RuntimeException("To update vaas order paid is failed.");
                }

                //TODO 发送消息出去，提示该订单需要自动处理
            }
        }

        return po;
    }

    @Override
    public BaseDto getPaymentOrderByTradeNo(final int userId, final String tradeNo) {
        PaymentOrder paymentOrder = paymentOrderDao.getPaymentOrderByTradeNo(tradeNo);
        if (paymentOrder == null) {
            BaseDto dto = new BaseDto();
            dto.setErrcode(404);
            dto.setErrmsg("不存在");
            return dto;
        }

        if (paymentOrder.getUserId() != userId) {
            BaseDto dto = new BaseDto();
            dto.setErrcode(403);
            dto.setErrmsg("无权限");
            return dto;
        }

        PaymentOrderDto dto = PaymentOrderDto.createdBy(paymentOrder);
        dto.setErrcode(0);
        return dto;
    }
}
